﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using MacomberMapSystem.Common.Serialization;
using MacomberMapSystem.Common.CIM;
using System.Data.Common;
using System.IO;
using System.Drawing;
using MacomberMapSystem.Common.Database;
using MacomberMapSystem.Common.Exports;

namespace MacomberMapSystem.Common.Processing
{
    /// <summary>
    /// This class produces RAS displays
    /// </summary>
    public class CIM_RemedialActionSchemeDisplay : CIM_Processor
    {

        /// <summary>
        /// Initilaize our RAS display
        /// </summary>
        /// <param name="xElem"></param>
        /// <param name="NamedParameters"></param>
        /// <param name="Repository"></param>
        public CIM_RemedialActionSchemeDisplay(XmlElement xElem, Dictionary<String, Object> NamedParameters, MM_Repository Repository)
            : base(xElem, NamedParameters, Repository)
        { }

        /// <summary>
        /// Report the process name for our element
        /// </summary>
        public override string ProcessName
        {
            get { return "Remedial Action Scheme One-Line Creator"; }
        }

        /// <summary>
        /// Initiate our process
        /// </summary>
        /// <param name="DbConn"></param>
        /// <returns></returns>
        public override CIM_Processor.enumProcessState InitiateProcess(Database.MM_Database_Connector DbConn)
        {
            //First, export every substation that has a gate.
            Database.MM_Database_Model Model = NamedParameters["Model"] as Database.MM_Database_Model;          

            List<CIM_Element> Substations = new List<CIM_Element>();
            List<CIM_Trace> BreakerToBreakers = new List<CIM_Trace>();

            foreach (CIM_Element RAS in Model.ElementsOfType("etx:RemedialActionScheme"))
                foreach (CIM_Element Elem in RAS.Elements)
                {
                    if (Elem.Substation != null && !Substations.Contains(Elem.Substation))
                        Substations.Add(Elem.Substation);
                    foreach (CIM_Trace AssocTrace in Elem.AssociatedTraces)
                        if (!BreakerToBreakers.Contains(AssocTrace))
                            BreakerToBreakers.Add(AssocTrace);
                }
            foreach (CIM_Element Gate in Model.ElementsOfType("etx:Gate"))
            {
                CIM_Element Sub;
                foreach (CIM_Element Term in Gate.Parse("<Pin*>Terminal", null))
                {
                    if ((Sub = Term.Substation) != null && !Substations.Contains(Sub))
                        Substations.Add(Sub);
                    foreach (CIM_Trace AssocTrace in Term.Elements[0].AssociatedTraces)
                        if (!BreakerToBreakers.Contains(AssocTrace))
                            BreakerToBreakers.Add(AssocTrace);
                }
            }         

            Current = 0;
            Total = Substations.Count + BreakerToBreakers.Count + 1;

            //First, export each substation
            int LastModel = Model.ID;
            if (Model.FullClass == null)
                foreach (int ModelNo in Repository.Model_Collection.Keys)
                    LastModel = Math.Max(LastModel, ModelNo);

            String TargetFolder = NamedParameters["TargetFolder"].ToString();
            String CompiledDirectory = TargetFolder, EMSDirectory = TargetFolder, ImageDirectory = TargetFolder;
            String ImageFolder = Path.Combine(TargetFolder, "Images");
            if (!Directory.Exists(ImageFolder))
                Directory.CreateDirectory(ImageFolder);

            //Make sure we have our ESet in place
            if (!File.Exists(Path.Combine(TargetFolder, "ercotonelines_eset.ddl")))
                using (StreamWriter sESET = new StreamWriter(Path.Combine(TargetFolder, "ercotonelines_eset.ddl"), false, Encoding.ASCII))
                    sESET.Write(MacomberMapSystem.Common.Integration.Data_Manager.WriteColorsAndModelSpecifics(Common.Properties.Resources.ERCOTOneLines_ESet, Model));




            //Write each one-line out for each substation, but don't need to compile right now.
            foreach (CIM_Element Sub in Substations)
                    using (DbCommand dCmd = Repository.Db.CreateCommand("SELECT * FROM MM_DATABASE_ONELINE WHERE RDFID=:0 AND MODELS LIKE :1", Sub.rdfID.ToString(), "%," + LastModel.ToString() + ",%"))
                    using (DbDataReader dRd = dCmd.ExecuteReader())
                        if (dRd.Read())                       
                            try
                            {
                                Current++;
                                String SubName = Sub.Name;
                                MM_Database_OneLine InLine = new MM_Database_OneLine(dRd, Model);
                                MM_Oneline_Export OLExport = new MM_Oneline_Export(InLine, Model);
                                using (MemoryStream OneLineImageStream = new MemoryStream((byte[])dRd["Image"]))
                                using (Image OneLineImage = Bitmap.FromStream(OneLineImageStream))
                                using (StreamWriter swSCADA = new StreamWriter(Path.Combine(TargetFolder, "SCADA-" + SubName + "_dset.ddl"), false, new UTF8Encoding(false)))
                                using (StreamWriter swNETMOM = new StreamWriter(Path.Combine(TargetFolder, "NETMOM-" + SubName + "_dset.ddl"), false, new UTF8Encoding(false)))
                                using (StreamWriter swOTS = new StreamWriter(Path.Combine(TargetFolder, "OTS-" + SubName + "_dset.ddl"), false, new UTF8Encoding(false)))
                                {
                                    MM_DDL_Exporter.ExportOneLine(InLine, Model, OneLineImage, OLExport, ImageDirectory, swSCADA, swNETMOM, swOTS, TargetFolder, Repository.Db.GetLastAssignment(InLine));
                                    OneLineImage.Save(Path.Combine(ImageFolder, SubName + ".png"), System.Drawing.Imaging.ImageFormat.Png);
                                }
                            }
                            catch (Exception ex)
                            { }

            //Now, export each breaker to breaker
            foreach (CIM_Trace BreakerToBreaker in BreakerToBreakers)
                try
                {
                    Current++;
                    XmlDocument xOneLine = CIM_BreakerToBreaker.AutoGenerateOneLine(BreakerToBreaker);
                    MacomberMapSystem.Common.User_Interfaces.One_Lines.clsTomSawyer.RunLayout(xOneLine, Repository);
                    MM_Database_OneLine OneLine = new MM_Database_OneLine(null, null);
                    OneLine.Document = xOneLine;
                    OneLine.Models = new MM_Database_Model[] { Model };
                    OneLine.Names = new string[] { BreakerToBreaker.Name };
                    OneLine.ID = -1;
                    OneLine.OneLineType = MM_Database_OneLine.OneLineTypeEnum.BreakerToBreaker;
                    OneLine.rdfID = BreakerToBreaker.rdfID;
                    MM_Oneline_Export OLExport = new MM_Oneline_Export(OneLine, Model);
                    MM_Database_Assignment LastAssignment = Repository.Db.GetLastAssignment(OneLine);
                    using (Bitmap OneLineImage = MM_Image_Exporter.OneLineImage(OneLine, Model, Model.LocateExport(OneLine), LastAssignment))
                    using (StreamWriter swSCADA = new StreamWriter(Path.Combine(TargetFolder, "SCADA-__" + BreakerToBreaker.Name + "_dset.ddl"), false, new UTF8Encoding(false)))
                    using (StreamWriter swNETMOM = new StreamWriter(Path.Combine(TargetFolder, "NETMOM-__" + BreakerToBreaker.Name + "_dset.ddl"), false, new UTF8Encoding(false)))
                    using (StreamWriter swOTS = new StreamWriter(Path.Combine(TargetFolder, "OTS-__" + BreakerToBreaker.Name + "_dset.ddl"), false, new UTF8Encoding(false)))
                    {
                        MM_DDL_Exporter.ExportOneLine(OneLine, Model, OneLineImage, OLExport, ImageDirectory, swSCADA, swNETMOM, swOTS, TargetFolder, LastAssignment);
                        OneLineImage.Save(Path.Combine(ImageFolder, "__" + BreakerToBreaker.Name + ".png"), System.Drawing.Imaging.ImageFormat.Png);
                    }

                }
                catch (Exception ex)
                { }




            MM_DDL_Exporter.WriteRASTabularDisplay(Model, TargetFolder);

            return enumProcessState.Completed;
        }
    }
}